package components.fte
{
    import components.events.FTELinkEvent;
    import components.utils.EventListenerUtil;
    
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;
    import flash.net.getClassByAlias;
    import flash.text.engine.BreakOpportunity;
    import flash.text.engine.ContentElement;
    import flash.text.engine.ElementFormat;
    import flash.text.engine.FontDescription;
    import flash.text.engine.FontLookup;
    import flash.text.engine.FontPosture;
    import flash.text.engine.FontWeight;
    import flash.text.engine.GraphicElement;
    import flash.text.engine.GroupElement;
    import flash.text.engine.TextBaseline;
    import flash.text.engine.TextBlock;
    import flash.text.engine.TextElement;
    import flash.text.engine.TextLine;
    import flash.text.engine.TextLineMirrorRegion;
    import flash.ui.Mouse;
    import flash.ui.MouseCursor;

    /**
     *图文混排
     * @author zn
     *
     */
    public class FTETextBlock extends EventDispatcher
    {
        /**
         *长度限制
         */
        public var lengthLimit:int = 200;

        /**
         *保留长度
         */
        public var remainderLength:int = 30;

        /**
         *是否启用长度限制
         */
        public var limitable:Boolean = false;

        protected var _sp:Sprite;

        protected var _yPos:Number = 0;

        protected var _textLineSpList:Array = [];

        protected var _width:Number;

        protected var _fontName:String = "";

        protected var _fontSize:Number = 0;

        protected var _fontColor:int = -1;

        protected var _textBlockList:Array = [];

        private var _fteElement:FTEElement;

        public function FTETextBlock(sp:Sprite, width:Number)
        {
            _sp = sp;
            _width = width;

            _fteElement = new FTEElement();
			EventListenerUtil.addEventListener(_fteElement,FTELinkEvent.LINK_CLICK, linkClickHandler);
        }

        public function append(value:String):void
        {
            var textBlock:TextBlock = new TextBlock(_fteElement.createElement(value));
            textBlock.baselineZero = TextBaseline.IDEOGRAPHIC_TOP;
            createLine(textBlock);
        }

        public function createLine(textBlock:TextBlock):void
        {
            var textLine:TextLine = textBlock.createTextLine(null, _width);
            var rect:Rectangle;
            var textLineSp:Sprite = new Sprite();
            var y:Number = 0;

            while (textLine)
            {
                textLineSp.addChild(textLine);
                textLine.y = y;
                y += textLine.height;
                textLine = textBlock.createTextLine(textLine, _width);
            }

            textBlock.releaseLineCreationData();

            textLineSp.y = _yPos;
            _yPos += textLineSp.height;
            _sp.addChild(textLineSp);

            _textBlockList.push(textBlock);
            _textLineSpList.push(textLineSp);

            removePartTextBlock();
        }

        /**
         *超出长度限制，去掉一些TextBlock
         *
         */
        protected function removePartTextBlock():void
        {
            if (limitable && _textBlockList.length > lengthLimit)
            {
                var displayObject:DisplayObject;
                while (_textBlockList.length > remainderLength)
                {
                    _textBlockList.shift();
                    displayObject = _textLineSpList.shift() as DisplayObject;
                    _sp.removeChild(displayObject);
                }

                displayObject = _textLineSpList[_textLineSpList.length - 1] as DisplayObject;

                _yPos = displayObject.y + displayObject.height;
            }
        }

        public function removeAll():void
        {
            for (var i:int = 0; i < _textLineSpList.length; i++)
            {
                _sp.removeChild(_textLineSpList[i] as DisplayObject);
            }
            _textLineSpList = [];

            _textBlockList = [];

            _yPos = 0;
        }

        public function get width():Number
        {
            return _width;
        }

        public function set width(value:Number):void
        {
            _width = value;

            refreshText();
        }

        protected function refreshText():void
        {
            var textBlockList:Array = _textBlockList.concat();
            removeAll();

            var textBlock:TextBlock;
            for (var i:int = 0; i < textBlockList.length; i++)
            {
                textBlock = textBlockList[i];
                createLine(textBlock);
            }
        }

        protected function linkClickHandler(event:FTELinkEvent):void
        {
            event.stopImmediatePropagation();
            dispatchEvent(new FTELinkEvent(event.data));
        }
    }
}
